package projectjet;

import Channel.ChooseChannel;
import history.GetPublicHistory;
import history.CreatePublicHistory;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.Socket;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class Session extends Thread{
	
	private Socket socket;
	private BufferedReader in;
	private BufferedWriter out;
	private String username;
	private CreatePublicHistory createHistory = new CreatePublicHistory();
	private List <String> listOfHistory = new ArrayList<String>();
	private GetPublicHistory history = new GetPublicHistory();
        private HoldingSessions sessions = new HoldingSessions();
        private Autentification autentification;
        private ChooseChannel chooseChannel;
	private String channel;
        
        public String getNameConnection() {
		return username;
	}
	
	public Session(Socket connection) throws IOException {
		this.socket = connection;
		this.in = new BufferedReader(new InputStreamReader(this.socket.getInputStream()));
		this.out = new BufferedWriter(new OutputStreamWriter(this.socket.getOutputStream()));
	}
        
 
        @Override
	public void run() {
            autentification = new Autentification(socket,in, out,this);
            chooseChannel = new ChooseChannel(autentification, in);
           // chooseChannel.getChannel();
            DateFormat df = new SimpleDateFormat("dd.mm.yyyy HH:mm:ss");
            createHistory.connectionToDataBase();

            if(autentification.getAuthentication() && chooseChannel.channelChoosed()){
                username = autentification.getUsername();
                try{
                    if(!this.isInterrupted()){
                            channel = chooseChannel.getChannel();
                            autentification.send("You entered to " + channel + " channel.");
                            sessions.getSessions().put(username, this);
                            sessions.getChannels().put(username, channel);
                            System.out.println("Client " + username + " was added to " + channel + " channel. ");
                    }

                }catch(Exception e){
                        System.out.println("ERRRRRRRRRRRRRRROR" + e.getMessage());
                        this.interrupt();
                }

                try{
                     while(!this.isInterrupted()) {
                        String line = this.in.readLine();
                        System.out.println(line);
                        if(line.equals("exit")) {
                            sessions.getSessions().remove(username);
                            sessions.getChannels().remove(username);
                            System.out.println("Client " + username + " leave chat. ");
                            this.socket.close();
                            break;
                        }
                        if(line.equals("all clients")) {
                            String message = "Clients online:";
                            System.out.println(sessions.getClientsOnlineByChannel(chooseChannel.getChannel()));
                            for (String user: sessions.getClientsOnlineByChannel(chooseChannel.getChannel())) {
                                if (!user.equals(username))
                                message +=user+"  ";
                            }
                            System.out.println("CLIENTS : "+message);
                            autentification.send(message);
                        }else{

                            if(line.toLowerCase().startsWith("pub_history")){
                                System.out.println(" Public HISTORY");
                                listOfHistory = history.getPubHistory(chooseChannel.getChannel());
                                for (int i=0; i<listOfHistory.size(); i++) {
                                System.out.println(listOfHistory.get(i));
                                autentification.send(listOfHistory.get(i));}
                            } 

                            else {  
                                if(line.toLowerCase().startsWith("private_history " )){
                                    System.out.println("Private HISTORY to " + line.split(" ")[1]);
                                    int emptyMessage=0;
                                    listOfHistory = history.getPrivateHistory(chooseChannel.getChannel(), line.split(" ")[1], username);
                                    for (int i=0; i<listOfHistory.size(); i++) {
                                        System.out.println(listOfHistory.get(i));
                                        autentification.send(listOfHistory.get(i));
                                        if(listOfHistory.get(i).equals("")) emptyMessage++;
                                    }
                                    if (emptyMessage==listOfHistory.size()) autentification.send("Your history with this user in this channel is empty");
                                } 
                                else { 
                                    if(line.equals("change channel")){
                                        sessions.getChannels().remove(channel);
                                        chooseChannel.channelChoosed();
                                        channel = chooseChannel.getChannel();
                                        autentification.send("You entered to " + channel + " channel.");
                                        sessions.getChannels().put(username, channel);
                                        System.out.println("Client " + username + " was added to " + channel + " channel. ");

                                    } else {
                                        String string = line;
                                        Pattern pattern = Pattern.compile("^(\\w+)\\s(->)\\s(.*)$");
                                        Matcher matcher = pattern.matcher(string);
                                        String data = df.format(new Date());
                                        if(!this.isInterrupted()){

                                            if(matcher.matches()){
                                                if(!matcher.group(1).equals(username)){
                                                        Session receiverSession = sessions.getClientSession(chooseChannel.getChannel(), matcher.group(1));
                                                        if(receiverSession == null)  autentification.send("Sorry, but such user is OFFLINE!!!");
                                                        else {
                                                        createHistory.addToHistory(chooseChannel.getChannel(), data, username, matcher.group(1) ,username+" : "+matcher.group(3));
                                                        receiverSession.autentification.send("[" + this.username + " : " + data + "] " + matcher.group(3));
                                                        }

                                                    }else autentification.send("Don't talt to yourself!!");

                                                }else {
                                                    createHistory.addToHistory(chooseChannel.getChannel(), data, username, "null", username+" : "+line);
                                                    for(String client: sessions.getClientsOnlineByChannel(chooseChannel.getChannel())){
                                                        if (!client.equals(this.username)){
                                                            sessions.getSessions().get(client).autentification.send("[" + this.username + ": " + data + "] " + line);
                                                        }
                                                    } 
                                                }
                                            } 
                                        } 
                                    }
                                }
                        }
                     }
                    }catch(Exception e){
                            sessions.getSessions().remove(username);
                            sessions.getChannels().remove(username);
                            System.out.println("Client " + username + " leave chat. ");

                            try {
                                    this.socket.close();

                            } catch (IOException e1) {
                                    System.out.println("Socket was closed with error!!");
                            }
                    }
            }
	}
}
